from rest_framework import serializers

#自定义关联属性输出
from apps.books.models import HeroInfo, BookInfo


class HeroRelateSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    hname = serializers.CharField()
class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    btitle = serializers.CharField()
    bpub_date = serializers.DateField()
    bread = serializers.IntegerField()

    #显示关系属性的英雄实例
    # heros = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
    # heros = serializers.StringRelatedField(read_only=True,many=True)
    heros = HeroRelateSerializer(read_only=True,many = True)


class BookRelatedSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False)
    btitle = serializers.CharField()
    bpub_date = serializers.DateField()
###使用  属性名 进行字段的验证
# def hname(attrs):
#     if '4' not in attrs:
#         raise serializers.ValidationError('必须里面有4')
#     return attrs
class HeroSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    hname = serializers.CharField(
        min_length=2,
        max_length=8,
        error_messages={
            'min_length':"英雄名字为3-8个字符",
            'max_length':'英雄名字为3-8个字符',
            'required':"英雄名必填"
        }#,
        #validators=[hname]
    )
    hgender = serializers.IntegerField(required=False)
    hcomment = serializers.CharField(required=False)
    hbook_id = serializers.IntegerField()
    #关系属性hbook==》BookInfo实例
    #需要序列化的数据中包含有其他的关联对象，则对关联对象数据外键进行序列化操作

    # 采用  PrimaryKeyRelatedField  将字段被序列化为关联对象的主键
    # hbook = serializers.PrimaryKeyRelatedField(read_only=True)

    #StringRelatedField   将字段被序列化为关联对象的字符串表达方式(__str__方法)
    # hbook = serializers.StringRelatedField(read_only=True)

    #自定义
    ###使用  属性名 进行字段的验证
    hbook = BookRelatedSerializer(read_only=True)


    # def validate_hname(self,attrs):
    #     if '123' not in attrs:
    #         raise serializers.ValidationError('必须里面有123')
    #     return attrs
###在序列化器中需要同时对实例里面的 多个字段进行比较验证
    def validate(self, attrs):
        hname = len(attrs['hname'])
        hcomment = len(attrs['hcomment'])
        if hname > hcomment:
            raise serializers.ValidationError('描述的长度必须大于名字的长度')
        return attrs

    def create(self, validated_data): #创建
        hero = HeroInfo.objects.create(**validated_data)
        return hero
    def update(self, instance, validated_data):#修改  validated_data里面的数据是验证后的字典
        #instance  需要修改的对象 原始对象
        instance.hname = validated_data.get('hname')
        if 'hgender' in validated_data:
            instance.hgender = validated_data.get('hgender')
        if 'hcomment' in validated_data:
            instance.hcomment = validated_data.get('hcomment')
        instance.save()
        return instance


#模型类序列化器modelserializer
class BookModelSerializer(serializers.ModelSerializer):
    """图书"""
    class Meta:
        model = BookInfo
        fields = "__all__"
#模型类序列化器modelserializer
class HeroModelSerializer(serializers.ModelSerializer):
    """图书"""
    class Meta:
        model = HeroInfo
        fields = ('id','hname','hgender','hcomment','hbook')
        extra_kwargs = {
            'hgender':{'required':True}  #必须添加hgender性别属性
        }
        # fields = "__all__"
        # read_only_fields = ('id','hcomment')# 表示可以为空 但是有些不能为空 列如hbook